Skip to content

Feature/psd animation#4

Open
aqiq-marine wants to merge 36 commits intoframe-script:mainfrom
aqiq-marine:feature/psd-animation
Open

Feature/psd animation#4
aqiq-marine wants to merge 36 commits intoframe-script:mainfrom
aqiq-marine:feature/psd-animation

Conversation

@aqiq-marine
Copy link

ゆっくり動画を簡単に作成するため、psdファイルを制御するコンポーネントを作成しました。
( #2 )

使用例

export const PROJECT = () => {
  const eyeUtilDict = {
      kind: "bool" as const,
      options: {
          Default: "顔パーツ/目/開き",
          Open: "顔パーツ/目/開き",
          HalfOpen: "顔パーツ/目/やや開き",
          HalfClosed: "顔パーツ/目/やや閉じ",
          Closed: "顔パーツ/目/閉じ",
      }
  }
  const mouthUtilDict = {
      kind: "bool" as const,
      options: {
          Default: "顔パーツ/口/閉じ",
          a: "顔パーツ/口/あ",
          i: "顔パーツ/口/い",
          u: "顔パーツ/口/う",
          e: "顔パーツ/口/え",
          o: "顔パーツ/口/お",
          x: "顔パーツ/口/閉じ",
      }
  }
  const LipSync = createLipSync(mouthUtilDict)
  const Blink = createBlink(eyeUtilDict)
  return (
    <Project>
      <TimeLine>
        <Clip label="Hello">
          <PsdCharacter psd="../assets/フリー.psd">
            <MotionSequence>
              <Block>
                <Voice voice="../assets/001.wav" volume={0.5} />
                <LipSync data={lipsync1} />
              </Block>
              <Voice voice="../assets/002.wav" />
            </MotionSequence>
            <Blink data={blink1} />
            <DeclareVariable variableName="t" initValue={0}>
              <DeclareAnimation f={async (ctx, variables) => {
                await ctx.move(variables["t"]).to(1, seconds(1), BEZIER_SMOOTH)
              }}>
                <Motion motion={(variables, frames) => {
                  const t = variables["t"].get(frames[0])
                  if (t == 1) {
                      return {}
                  } else if (t < 0.5) {
                    return {
                      [eyeUtilDict.options.Open]: false,
                      [eyeUtilDict.options.Closed]: true,
                    }
                  } else {
                    return {
                      [eyeUtilDict.options.Open]: true,
                      [eyeUtilDict.options.Closed]: false,
                    }
                  }
                }} />
              </DeclareAnimation>
            </DeclareVariable>
          </PsdCharacter>
        </Clip>
      </TimeLine>
    </Project>
  )
}

@bea4dev
Copy link
Contributor

bea4dev commented Mar 9, 2026

ありがとうございます!
近日中できるだけ早くレビューしますのでしばらくお待ち下さい。

@bea4dev
Copy link
Contributor

bea4dev commented Mar 16, 2026

おまたせしました。
全体的には良さそうなのですが、いくつかコメントさせてください。

  1. 最初のコード例について
<MotionSequence>
  <Block>
    <Voice voice="../assets/001.wav" volume={0.5} />
    <LipSync data={lipsync1} />
  </Block>
  <Voice voice="../assets/002.wav" />
</MotionSequence>
<Blink data={blink1} />

ここの部分、<Block>が何を指しているのかがやや不明瞭なのと、lipsync1blink1は何を指しているのでしょうか?

  1. DeclareVariableについて
    ここは好みが出る部分かもしれませんが、variableName="t"というように生のstringを渡すのにはやや抵抗があります。
    ここはどちらかといえばVariableReferenceのような型を作って静的に解決しやすいようにしてtypoを排除しやすくするという方向性のほうが健全かなと考えています。
    ただ、コレに関しては絶対的にこちらが正しいというわけではないと思うので、これを採用するかどうかはおまかせします。

@aqiq-marine
Copy link
Author

不明瞭な部分も多くすみません。
いくつか補足します。

  1. 1.のlipsync, blinkについてです。
    LipSync内で使用していたlipsync1についてはrhubarbの出力ファイルに合わせる形で次のような形式のデータとなっています。
    start, endが時系列の区間、valueが口の形に対応しています。
type HasKey<K extends string, V = unknown> = {
  [P in K]: V
} & Record<string, unknown>

export type LipSyncData  = HasKey<"mouthCues", {start: number, end: number, value: string}[]>

const blink1 = {
  mouthCues: [
    { start: 0.00, end: 0.03, value: "X" },
    { start: 0.03, end: 0.09, value: "B" },
    { start: 0.09, end: 0.29, value: "C" }
}

Blink内のblink1についてもこれにならって次のようなデータになっています。

export type BlinkData = HasKey<"blinkCues", {start: number, end: number, value: string}[]>
  1. 1.のBlockについてです
    確かに少し広すぎる名前でした。
    機能としてはMotionSequence, BlockがそれぞれClipSequence, Clipに相当するようなものです。
    もっと絞ってParallelBlockなどのほうが良いでしょうか?

  2. 2.についてです。
    この実装となっている理由としては単に実装上容易だったというだけであり、可能であれば型で解決したいところではあります。
    しかし私自身typescriptに慣れていないところがあり、まだ実装イメージができていないので、これに関しては少し待ってもらっていいでしょうか?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants